home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ABUSESRC.ZIP
/
AbuseSrc
/
abuse
/
src
/
chars.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-24
|
15KB
|
579 lines
#include "chars.hpp"
#include "game.hpp"
#include "intsect.hpp"
#include "lisp.hpp"
#include "jwindow.hpp"
#include "input.hpp"
#include "id.hpp"
#include "clisp.hpp"
#include "dprint.hpp"
#include "lisp_gc.hpp"
#define FADING_FRAMES 26
#define FADING_MAX 32
character_type **figures;
int total_weapons=0;
int *weapon_types=NULL; // maps 0..total_weapons into 'real' weapon type
char *state_names[MAX_STATE]= {
"dead",
"dieing",
"stopped",
"start_run_jump","run_jump","run_jump_fall","end_run_jump",
"flinch_up","flinch_down",
"morph_pose",
"running" };
/* "start_still_jump","still_jump","still_jump_fall","end_still_jump",
"morph_pose",
"walking",
"weapon_draw",
"weapon_put_away",
"weapon_fire",
"weapon_end_fire",
"weapon_fire_up",
"weapon_end_fire_up",
"blocking",
"block_recoil",
"turn_around",
"flinch_up","flinch_down","flinch_back",
"flinch_air","flinch_ground","flinch_getup","woze",
"stance"
} ; */
char *cflag_names[TOTAL_CFLAGS]={"hurt_all","is_weapon","stoppable","can_block",
"hurtable","pushable","unlistable",
"add_front","cached_in","need_cache_in","unactive_shield"};
char *ofun_names[TOTAL_OFUNS]={"ai_fun","move_fun","draw_fun","map_draw_fun","damage_fun",
"next_state_fun","user_fun",
"constructor","reload_fun","get_cache_list_fun",
"type_change_fun"};
int character_type::add_state(void *symbol) // returns index into seq to use
{
if (item_type(symbol)!=L_SYMBOL)
{
lprint(symbol);
lbreak("is not a symbol (in def_char)");
exit(0);
}
void *val=symbol_value(symbol);
int num;
if (DEFINEDP(val))
{
if (item_type(val)!=L_NUMBER)
{
lprint(symbol);
dprintf("expecting symbol value to be a number, instead got : ");
lprint(val);
lbreak("");
exit(0);
}
num=lnumber_value(val);
} else
{
num=ts;
if (num<MAX_STATE) num=MAX_STATE;
int sp=current_space;
current_space=PERM_SPACE;
set_symbol_number(symbol,num);
current_space=sp;
}
if (num<ts && seq[num])
{
lprint(symbol);
lbreak("symbol has been assigned value %d, but value already in use by state %s\n"
"use a different symbol for this state\n",
lstring_value(symbol_name(seq_syms[num])));
exit(0);
} else if (num>=ts)
{
seq=(sequence **)jrealloc(seq,sizeof(sequence *)*(num+1),"state list");
seq_syms=(void **)jrealloc(seq_syms,sizeof(void *)*(num+1),"state sym list");
memset(&seq[ts],0,sizeof(sequence *)*((num+1)-ts));
memset(&seq_syms[ts],0,sizeof(void *)*((num+1)-ts));
ts=num+1;
}
seq_syms[num]=symbol;
return num;
}
int flinch_state(character_state state)
{
if (state==flinch_up || state==flinch_down)
return 1;
else return 0;
}
int character_type::cache_in() // returns false if out of cache memory
{
int i;
if (get_cflag(CFLAG_CACHED_IN))
return 1;
cflags|=1<<CFLAG_CACHED_IN;
for (i=0;i<ts;i++)
{
if (seq[i])
seq[i]->cache_in();
}
return 1;
}
void character_type::add_sequence(character_state which, sequence *new_seq)
{
if (seq[which])
delete seq[which];
seq[which]=new_seq;
}
void *l_obj_get(long number) // exten lisp function switches on number
{
character_type *t=figures[current_object->otype];
if (t->tiv<=number || !t->vars[number])
{
lbreak("access : variable does not exsist for this class\n");
return 0;
}
return new_lisp_number(current_object->lvars[t->var_index[number]]);
}
void l_obj_set(long number, void *arg) // exten lisp function switches on number
{
character_type *t=figures[current_object->otype];
if (t->tiv<=number || !t->vars[number])
{
lbreak("set : variable does not exsist for this class\n");
return;
}
current_object->lvars[t->var_index[number]]=lnumber_value(arg);
}
void l_obj_print(long number) // exten lisp function switches on number
{
character_type *t=figures[current_object->otype];
if (t->tiv<=number || !t->vars[number])
{
lbreak("access : variable does not exsist for this class\n");
return;
}
dprintf("%d",current_object->lvars[t->var_index[number]]);
}
void character_type::add_var(void *symbol, void *name)
{
/* First see if the variable has been defined for another object
if so report a conflict if any occur */
lisp_symbol *s=(lisp_symbol *)symbol;
if (DEFINEDP(s->value) && (item_type(s->value)!=L_OBJECT_VAR))
{
lprint(symbol);
lbreak("symbol already has a value, cannot instantiate an object varible");
exit(0);
} else if (DEFINEDP(s->value))
{
int index=((lisp_object_var *)s->value)->number;
if (index<tiv)
{
if (vars[index])
{
lbreak("While defining object %s :\n"
" var '%s' was previously defined by another\n"
" with index %d, but %s has a var listed '%s' with same index\n"
" try moving definition of %s before previously declared object",
lstring_value(symbol_name(name)),
lstring_value(symbol_name(symbol)),
index,
lstring_value(symbol_name(name)),
lstring_value(symbol_name(vars[index])),
lstring_value(symbol_name(name))
);
exit(0);
} else
{
var_index[index]=tv;
vars[index]=symbol;
tv++;
}
} else
{
int new_total=index+1;
vars=(void **)jrealloc(vars,sizeof(void *)*new_total,"variable name list");
var_index=(short *)jrealloc(var_index,sizeof(short)*new_total,"variable index");
memset(&vars[tiv],0,(new_total-tiv)*sizeof(void *));
memset(&var_index[tiv],0,(new_total-tiv)*sizeof(short));
tiv=new_total;
var_index[index]=tv;
vars[index]=symbol;
tv++;
}
} else /** Nope, looks like we have to add the variable ourself and define the assesor funs */
{
/* locate a free index in the index list */
int free_index=tiv;
for (int i=0;i<tiv;i++)
if (!vars[i] && i<tiv) free_index=i;
if (free_index==tiv)
{
int new_total=free_index+1;
vars=(void **)jrealloc(vars,sizeof(void *)*new_total,"variable name list");
var_index=(short *)jrealloc(var_index,sizeof(short)*new_total,"variable index");
memset(&vars[tiv],0,(new_total-tiv)*sizeof(void *));
memset(&var_index[tiv],0,(new_total-tiv)*sizeof(short));
tiv=new_total;
}
/* create the var and add to var list */
int sp=current_space;
current_space=PERM_SPACE;
add_c_object(symbol,free_index);
vars[free_index]=symbol;
var_index[free_index]=tv;
tv++;
current_space=sp;
}
}
long character_type::isa_var_name(char *name)
{
int i=0;
for (;i<TOTAL_OBJECT_VARS;i++)
{
if (!strcmp(object_descriptions[i].name,name))
return 1;
}
for (i=0;i<tiv;i++)
if (!strcmp(lstring_value(symbol_name(vars[i])),name))
return 1;
return 0;
}
character_type::character_type(void *args, void *name)
{
p_ref r2(args);
int i;
ts=tv=0;
seq=NULL;
seq_syms=NULL;
vars=NULL;
var_index=NULL;
tiv=0;
void *l_abil= make_find_symbol("abilities");
void *l_funs= make_find_symbol("funs");
void *l_states=make_find_symbol("states");
void *l_flags= make_find_symbol("flags");
void *l_range= make_find_symbol("range");
void *l_draw_range= make_find_symbol("draw_range");
void *l_fields=make_find_symbol("fields");
void *l_logo= make_find_symbol("logo");
void *l_vars= make_find_symbol("vars");
memset(fun_table,0,sizeof(fun_table)); // destory all hopes of fun
fields=NULL;
cflags=0;
morph_mask=-1;
morph_power=0;
total_fields=0;
logo=-1;
rangex=rangey=0;
draw_rangex=draw_rangey=0;
for (i=0;i<TOTAL_ABILITIES;i++)
abil[i]=get_ability_default((ability)i);
void *field=args;
p_ref r7(field);
for (;field;field=CDR(field))
{
void *f=CAR(CAR(field));
p_ref r1(f);
if (f==l_abil)
{
void *l=CDR(CAR(field));
p_ref r4(l);
for (i=0;i<TOTAL_ABILITIES;i++)
{
Cell *ab=assoc(make_find_symbol(ability_names[i]),l);
p_ref r5(ab);
if (!NILP(ab))
abil[i]=lnumber_value(eval(lcar(lcdr(ab))));
}
} else if (f==l_funs)
{
void *l=CDR(CAR(field));
p_ref r4(l);
for (i=0;i<TOTAL_OFUNS;i++)
{
Cell *ab=assoc(make_find_symbol(ofun_names[i]),l);
p_ref r5(ab);
if (!NILP(ab) && lcar(lcdr(ab)))
fun_table[i]=lcar(lcdr(ab));
}
} else if (f==l_flags)
{
void *l=CDR(CAR(field));
p_ref r4(l);
for (i=0;i<TOTAL_CFLAGS;i++)
{
Cell *ab=assoc(make_find_symbol(cflag_names[i]),l);
p_ref r5(ab);
if (!NILP(ab) && eval(lcar(lcdr(ab))))
cflags|=(1<<i);
}
if (get_cflag(CFLAG_IS_WEAPON)) // if this is a weapon add to weapon array
{
total_weapons++;
weapon_types=(int *)jrealloc(weapon_types,sizeof(int)*total_weapons,"weapon map");
weapon_types[total_weapons-1]=total_objects;
}
} else if (f==l_range)
{
rangex=lnumber_value(eval(lcar(lcdr(lcar(field)))));
rangey=lnumber_value(eval(lcar(lcdr(lcdr(lcar(field))))));
} else if (f==l_draw_range)
{
draw_rangex=lnumber_value(eval(lcar(lcdr(lcar(field)))));
draw_rangey=lnumber_value(eval(lcar(lcdr(lcdr(lcar(field))))));
} else if (f==l_states)
{
void *l=CDR(CAR(field));
p_ref r4(l);
char fn[100];
strcpy(fn,lstring_value(eval(CAR(l)))); l=CDR(l);
while (l)
{
int index;
void *e;
sequence *mem;
index = add_state(CAR((CAR(l))));
e = eval(CAR(CDR(CAR(l))));
mem = new sequence(fn,e,NULL);
seq[index]=mem;
l=CDR(l);
}
} else if (f==l_fields)
{
void *mf=CDR(CAR(field));
p_ref r4(mf);
while (!NILP(mf))
{
char *real=lstring_value(eval(lcar(lcar(mf))));
char *fake=lstring_value(eval(lcar(lcdr(lcar(mf)))));
if (!isa_var_name(real))
{
lprint(field);
lbreak("fields : no such var name \"%s\"\n",name);
exit(0);
}
total_fields++;
fields=(named_field **)jrealloc(fields,sizeof(named_field *)*total_fields,"named_fields");
fields[total_fields-1]=new named_field(real,fake);
mf=lcdr(mf);
}
} else if (f==l_logo)
{
char *fn=lstring_value(eval(CAR(CDR(CAR(field)))));
char *o=lstring_value(eval(CAR(CDR(CDR(CAR(field))))));
logo=cash.reg(fn,o,SPEC_IMAGE,1);
} else if (f==l_vars)
{
void *l=CDR(CAR(field));
p_ref r8(l);
while (l)
{
add_var(CAR(l),name);
l=CDR(l);
}
}
else
{
lprint(lcar(field));
lbreak("Unknown field for character definiltion");
exit(0);
}
}
if (!seq[stopped])
lbreak("object (%s) has no stopped state, please define one!\n",
lstring_value(symbol_name(name)));
/* char *fn=lstring_value(lcar(desc));
if (!fn)
{
printf("No filename given for def-character (%s)\n",name);
exit(0);
}
desc=lcdr(desc); // skip filename
Cell *mrph=assoc(l_morph,desc); // check for morph info
morph_power=0;
if (!NILP(mrph))
{
mrph=lcdr(mrph);
morph_mask=cash.reg_object(fn,lcar(mrph),SPEC_IMAGE,1);
morph_power=lnumber_value(lcar(lcdr(mrph)));
} else morph_mask=-1;
Cell *sa=assoc(l_state_art,desc);
if (NILP(sa))
{
printf("missing state state art in def-character (%s)\n",name);
exit(0);
}
sa=lcdr(sa); // list of state sequences
while (!NILP(sa))
{
int num=lnumber_value(lcar(lcar(sa)));
if (seq[num])
printf("Warning : state '%s' defined multiply for object %s\n"
" using first definition\n",state_names[num],name);
else
seq[lnumber_value(lcar(lcar(sa)))]=new sequence(fn,lcar(lcdr(lcar(sa))),lcar(lcdr(lcdr(lcar(sa)))));
sa=lcdr(sa);
}
Cell *range=assoc(l_range,desc);
if (!NILP(range))
{
rangex=lnumber_value(lcar(lcdr(range)));
rangey=lnumber_value(lcar(lcdr(lcdr(range))));
} else
{
rangex=100;
rangey=50;
}
Cell *mf=assoc(l_fields,desc);
if (!NILP(mf))
{
mf=lcdr(mf);
total_fields=0;
while (!NILP(mf))
{
char *name=lstring_value(lcar(lcar(mf)));
int t=default_simple.total_vars(),find=-1;
for (int i=0;find<0 && i<t;i++)
if (!strcmp(default_simple.var_name(i),name))
find=i;
if (find<0)
{
lprint(assoc(l_fields,desc));
printf("fields : no such var name \"%s\"\n",name);
printf("current possiblities are : \n");
for (int i=0;i<t;i++) printf("\"%s\" ",default_simple.var_name(i));
printf("\n");
exit(0);
}
char *new_name=lstring_value(lcar(lcdr(lcar(mf))));
total_fields++;
fields=(named_field **)jrealloc(fields,sizeof(named_field *)*total_fields,"named_fields");
fields[total_fields-1]=new named_field(find,new_name);
mf=lcdr(mf);
}
} else total_fields=0;
Cell *lg=assoc(l_logo,desc);
if (NILP(lg))
{
if (get_cflag(CFLAG_IS_WEAPON))
{
lprint(desc);
lbreak("object must have a logo defined if it is a weapon\n"
"example '(logo . (""art/misc.spe"" . ""big waepon""))\n");
}
logo=-1;
}
else
logo=cash.reg_object(fn,lcdr(lg),SPEC_IMAGE,1);
*/
}
sequence *character_type::get_sequence(character_state s)
{
if (seq[s])
return seq[s];
else return seq[stopped];
}
character_type::~character_type()
{
for (int i=0;i<ts;i++)
if (seq[i])
delete seq[i];
if (ts) jfree(seq);
if (total_fields)
{
for (int i=0;i<total_fields;i++)
delete fields[i];
jfree(fields);
}
if (ts)
jfree(seq_syms);
if (tiv)
{
jfree(vars);
jfree(var_index);
}
}
extern long small_ptr_size(void *ptr);
void chk_sizes()
{
for (int i=0;i<total_objects;i++)
{
figures[i]->check_sizes();
}
}
void character_type::check_sizes()
{
for (int i=0;i<ts;i++)
if (seq[i] && small_ptr_size(seq[i])!=8)
printf("bad size for state %d\n",i);
}